home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / triv_lib / trivstrv.c < prev   
Encoding:
C/C++ Source or Header  |  1995-03-15  |  4.4 KB  |  105 lines

  1. /******************************************************************************
  2. * TrivSTrv.c - Construct a trivariate using a set of surfaces.                *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "triv_loc.h"
  8.  
  9. /*****************************************************************************
  10. * DESCRIPTION:                                                               M
  11. * Constructs a trivariate using a set of surfaces. Surfaces are made to be   M
  12. * compatible and then each is substituted into the new trivariate's mesh as  M
  13. * a row.                                     M
  14. *   If the OtherOrder is less than the number of curves, number of curves is M
  15. * used.                                         M
  16. *   A knot vector is formed with uniform open end for the other direction,   M
  17. * so it interpolates the first and last surfaces.                     M
  18. *   Note, however, that only the first and the last surfaces are         M
  19. * interpolated if OtherOrder is greater than 2.                              M
  20. *                                                                            *
  21. * PARAMETERS:                                                                M
  22. *   SrfList:      List of surfaces to consturct a trivariate with.           M
  23. *   OtherOrder:   Other, third, order of trivariate.                  M
  24. *                                                                            *
  25. * RETURN VALUE:                                                              M
  26. *   TrivTVStruct *:  Constructed trivariate from surfaces.                   M
  27. *                                                                            *
  28. * KEYWORDS:                                                                  M
  29. *   TrivTVFromSrfs, trivar constructors                                      M
  30. *****************************************************************************/
  31. TrivTVStruct *TrivTVFromSrfs(CagdSrfStruct *SrfList, int OtherOrder)
  32. {
  33.     CagdBType IsNotRational;
  34.     int i, j, NumSrfs, UOrder, VOrder, WOrder, MaxCoord, Length;
  35.     CagdRType **TVPoints;
  36.     CagdSrfStruct *Srf, **SrfVec;
  37.     TrivTVStruct *TV;
  38.  
  39.     /* Find out how many curves we have and put them in a linear vector.     */
  40.     /* Note the vector have a COPY of the curves so we can modify them.      */
  41.     for (NumSrfs = 0, Srf = SrfList;
  42.      Srf != NULL;
  43.      NumSrfs++, Srf = Srf -> Pnext);
  44.     SrfVec = (CagdSrfStruct **) IritMalloc(sizeof(CagdSrfStruct *) * NumSrfs);
  45.     for (i = 0, Srf = SrfList;
  46.      i < NumSrfs;
  47.      i++, Srf = Srf -> Pnext)
  48.     SrfVec[i] = CagdSrfCopy(Srf);
  49.  
  50.     /* Traverse vector in a O(n^2) fashion and make all curves compatible.   */
  51.     for (i = 0; i < NumSrfs - 1; i++)
  52.     for (j = i + 1; j < NumSrfs; j++)
  53.         CagdMakeSrfsCompatible(&SrfVec[i], &SrfVec[j],
  54.                    TRUE, TRUE, TRUE, TRUE);
  55.  
  56.     /* Construct the surface. All required information is now available.     */
  57.     UOrder = SrfVec[0] -> UOrder;
  58.     VOrder = SrfVec[0] -> VOrder;
  59.     WOrder = MIN(NumSrfs, OtherOrder);
  60.     if (NumSrfs == WOrder && SrfVec[0] -> GType == CAGD_CBEZIER_TYPE) {
  61.         /* Allocate a bezier surface. */
  62.     TV = TrivBzrTVNew(SrfVec[0] -> ULength, SrfVec[0] -> VLength,
  63.               NumSrfs, SrfVec[0] -> PType);
  64.     }
  65.     else {
  66.     /* Allocate a bspline surface. */
  67.     TV = TrivBspTVNew(SrfVec[0] -> ULength, SrfVec[0] -> VLength,
  68.               NumSrfs, UOrder, VOrder, WOrder,
  69.               SrfVec[0] -> PType);
  70.     IritFree((VoidPtr) TV -> UKnotVector);
  71.     TV -> UKnotVector = BspKnotCopy(SrfVec[0] -> UKnotVector,
  72.                     CAGD_SRF_UPT_LST_LEN(SrfVec[0]) +
  73.                     UOrder);
  74.     IritFree((VoidPtr) TV -> VKnotVector);
  75.     TV -> VKnotVector = BspKnotCopy(SrfVec[0] -> VKnotVector,
  76.                     CAGD_SRF_VPT_LST_LEN(SrfVec[0]) +
  77.                     VOrder);
  78.     BspKnotUniformOpen(NumSrfs, WOrder, TV -> WKnotVector);
  79.     }
  80.  
  81.     /* Substitute each curve as a row into the surface mesh and delete it. */
  82.     TVPoints = TV -> Points;
  83.     i = 0;
  84.     MaxCoord = CAGD_NUM_OF_PT_COORD(SrfVec[0] -> PType),
  85.     IsNotRational = !CAGD_IS_RATIONAL_SRF(SrfVec[0]);
  86.     Length = SrfVec[0] -> ULength * SrfVec[0] -> VLength;
  87.  
  88.     for (j = 0; j < NumSrfs; j++) {
  89.     int k;
  90.     CagdRType
  91.         **SrfPoints = SrfVec[j] -> Points;
  92.  
  93.         for (k = IsNotRational; k <= MaxCoord; k++)
  94.         CAGD_GEN_COPY(&TVPoints[k][i], SrfPoints[k],
  95.               sizeof(CagdRType) * Length);
  96.  
  97.     CagdSrfFree(SrfVec[j]);
  98.     i += Length;
  99.     }
  100.  
  101.     IritFree((VoidPtr) SrfVec);
  102.  
  103.     return TV;
  104. }
  105.